package com.mms.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mms.enumerate.*;
import com.mms.pojo.Medical;
import com.mms.pojo.Reserve;
import com.mms.pojo.UserInfo;
import com.mms.service.IMedicalHistoryService;
import com.mms.service.IMedicalService;
import com.mms.service.IReserveService;
import com.mms.utils.LayUiPage;
import com.mms.utils.RetJsonFaster;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * 预约表控制器
 * </p>
 *
 * @author 陈林鹏
 * @since 2021-04-14
 */
@Controller
@RequestMapping("/reserve")
public class ReserveController {

    /**
     * 预约服务
     */
    @Autowired
    IReserveService reserveService;

    /**
     * 医务表
     */
    @Autowired
    IMedicalService medicalService;

    /**
     * 病历服务
     */
    @Autowired
    IMedicalHistoryService medicalHistoryService;


    /*****用户操作接口******/
    /**
     * 获取用户的预约表信息
     *
     * @param request
     * @param pageNum
     * @param limit
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/UserReserves")
    public String getUserReserveInformation(HttpServletRequest request
            , @RequestParam(value = "page") String pageNum, String limit) {

        //定一个 分页变量
        Page page = LayUiPage.parse(pageNum, limit);
        //用于返回json
        JSONObject retJson = new JSONObject();
        //获取userinfo 用户信息
        HttpSession session = request.getSession();
        UserInfo userinfo = (UserInfo) session.getAttribute("userinfo");
        //判断是否 为空 空的 就是没有登录
        if (userinfo == null) {
            retJson.put("code", "0");
            retJson.put("msg", "请先登录");
            return retJson.toString();
        }
        //到服务层查找用户的 预约表
        List<Map<String, Object>> maps = reserveService.patientShow(userinfo
                , null
                , true);

        //打包返回的数据
        retJson.put("code", "0");
        retJson.put("msg", "成功");
        if (page != null) {
            retJson.put("count", page.getTotal());
        }
        retJson.put("data", maps);
        //清理分页
        PageHelper.clearPage();

        //返回数据
        return retJson.toString(SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 查询 预约历史
     *
     * @param request
     * @param pageNum
     * @param limit
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/Completed")
    public String Completed(HttpServletRequest request
            , @RequestParam(value = "page") String pageNum, String limit) {
        //设置返回 json 对象
        JSONObject retJson = new JSONObject();
        //设置分页
        Page page = LayUiPage.parse(pageNum, limit);
        //获取用户信息
        UserInfo userinfo = (UserInfo) request.getSession().getAttribute("userinfo");
        if (userinfo == null) {
            return CodeEnum.noSignIn.toString();
        }


        retJson.put("code", 0);
        retJson.put("msg", "获取成功");

        retJson.put("data", reserveService.completed(userinfo));
        if (page != null) {
            retJson.put("count", page.getTotal());
        }
        page.close();
        return retJson.toString(SerializerFeature.DisableCircularReferenceDetect);
    }


    /**
     * 用户更新数据
     *
     * @param request
     * @param id
     * @param timeOfAppointment
     * @param illnessDesc
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/updateTimeOfAppointment")
    public String updateTimeOfAppointment(HttpServletRequest request, int id
            , @RequestParam(value = "TIME_OF_APPOINTMENT") Date timeOfAppointment
            , @RequestParam(value = "illness_desc") String illnessDesc) {
        UserInfo userinfo = (UserInfo) request.getSession().getAttribute("userinfo");
        if (userinfo == null) {
            return RetJsonFaster.noSignIn();
        }

        //获取现在时间
        if (timeOfAppointment != null) {
            Date date = new Date();
            //预约时间必须大于 现在时间 2 小时
            if (date.getTime() + 7200000L > timeOfAppointment.getTime()) {
                return RetJsonFaster.unavailableDate();
            }
        }

        JSONObject retJson = new JSONObject();
        Reserve reserve = new Reserve();
        if (timeOfAppointment != null)
            reserve.setTimeOfAppointment(timeOfAppointment);
        //设置要修改的 预约表的Id
        reserve.setId(id);
        //设置病情描述
        if (illnessDesc != null && !illnessDesc.equals(""))
            reserve.setIllnessDesc(illnessDesc);
        reserve.setLastUpdateDate(new Date());
        reserve.setLastUpdateUsername(userinfo.getNickname());
        //定义 where
        Wrapper<Reserve> wrapper = new EntityWrapper();
        wrapper.where("user_info_id={0} " +
                        "and id={1}"
                , userinfo.getId()
                , reserve.getId())
                .ne("flow_progress", ReserveFlowProgress.appointment.getKey())
                .ne("flow_progress", ReserveFlowProgress.UserCancel.getKey())
                .ne("flow_progress", ReserveFlowProgress.discharged.getKey());
        //更新数据库
        boolean update = reserveService.update(reserve, wrapper);
        //如果修改失败
        if (update == false) {
//            返回修改失败
            return CodeEnum.ModificationFailed.toString();
        }
        retJson.put("code", 0);
        retJson.put("msg", "修改成功");
        retJson.put("boolean", update);
        return retJson.toString();
    }

    /**
     * 用户 预约 看病
     *
     * @param request
     * @param reserve
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "makeAnAppointment")
    public String makeAnAppointment(HttpServletRequest request, Reserve reserve) {
        //创建一个返回 json对象
        UserInfo userinfo = (UserInfo) request.getSession().getAttribute("userinfo");
        if (userinfo == null) {
            return RetJsonFaster.noSignIn();
        }
        JSONObject retJson = new JSONObject();
        //判断是否接收到了 预约信息
        if (reserve == null) {
            retJson.put("code", -1);
            retJson.put("msg", "没接收到任何数据");
            return retJson.toString();
        }
        //判断 预约日期 是否为空
        if (reserve.getTimeOfAppointment() == null) {
            retJson.put("code", -1);
            retJson.put("msg", "请填写日期");
            return retJson.toString();
        }
        //判断描述是否为空
        if (reserve.getIllnessDesc().equals("")) {
            retJson.put("code", -1);
            retJson.put("msg", "请填写描述信息");
            return retJson.toString();
        }
        //判断看各个类型 格式 是否 有误
        if (reserve.getDiagnoseType() == null ||
                !EnumTool.exists(ReserveDiagnoseType.class, reserve.getDiagnoseType()) ||
                reserve.getWardType() == null ||
                !EnumTool.exists(ReserveWardType.class, reserve.getWardType())) {
            retJson.put("code", -1);
            retJson.put("msg", "数据格式错误");
            return retJson.toString();
        }
        //获取现在时间
        Date date = new Date();
        //预约时间必须大于 现在时间 2 小时
        if (date.getTime() + 7200000L > reserve.getTimeOfAppointment().getTime()) {
            retJson.put("code", -1);
            retJson.put("msg", "日期只能是现在 2 小时后");
            return retJson.toString();
        }
        //插入预约数据
        if (!reserveService.makeAppointment(userinfo, reserve)) {
            retJson.put("code", -1);
            retJson.put("msg", "预约失败");
            return retJson.toString();
        }

        //返回成功提示
        retJson.put("code", 0);
        retJson.put("msg", "预约成功");
        return retJson.toString();
    }

    /**
     * 取消预约
     *
     * @param request
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "cancelReservation")
    public String cancelReservation(HttpServletRequest request
            , @RequestParam(value = "id[]") int[] id) {
        JSONObject retJson = new JSONObject();
        //判断 参数 是否为空
        if (id == null) {
            retJson.put("code", -1);
            retJson.put("msg", "参数有误");
            return retJson.toString();
        }
        //判断 用户信息 是否为空
        UserInfo userinfo = (UserInfo) request.getSession().getAttribute("userinfo");
        if (userinfo == null) {
            retJson.put("code", -1);
            retJson.put("msg", "请先登录");
            return retJson.toString();
        }
        //bug
        //执行 取消预约
        reserveService.cancelReservation(userinfo, id);
        //封装json 返回
        retJson.put("code", 0);
        retJson.put("msg", "取消预约成功");
        return retJson.toString();
    }

    /*****用户操作接口******/


    /**********医生操作接口***********/

    /**
     * 获取所有待处理的信息
     *
     * @param pageNum
     * @param limit
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "appointmentNotProcessed")
    public String appointmentNotProcessed(
            @RequestParam(value = "page") String pageNum, String limit) {
        Page page = LayUiPage.parse(pageNum, limit);


        JSONObject retJson = new JSONObject();
        retJson.put("code", 0);
        retJson.put("data", reserveService.patientShow(true
                , ReserveFlowProgress.processed.getKey()));
        retJson.put("msg", "获取成功");

        retJson.put("count", page.getTotal());
        return retJson.toString(SerializerFeature.DisableCircularReferenceDetect);
    }


    /**
     * 医生接受 预约信息
     *
     * @param request
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "acceptAppointment")
    public String acceptAppointment(
            HttpServletRequest request, @RequestParam(value = "id[]") Integer[] id) {
        //获取用户信息
        UserInfo userinfo = (UserInfo) request.getSession().getAttribute("userinfo");
        if (userinfo == null) {
//            == null 返回 请先登录
            return CodeEnum.noSignIn.toString();
        }
        //通过用户获取 medical 信息
        Medical medical = medicalService.getMedicalByUserInfo(userinfo);
        if (medical == null) {
            return CodeEnum.notDoctor.toString();
        }

        try {
//            接受预约
            reserveService.acceptAppointment(medical, id);
        } catch (Exception e) {
            e.printStackTrace();
//            异常返回 获取失败
            return CodeEnum.AcquisitionFailed.toString();
        }
//        定义打包返回数据
        JSONObject retJson = new JSONObject();

        retJson.put("code", 0);
        retJson.put("msg", "接受处理成功");
        return retJson.toString();
    }

    /**
     * 拒绝处理预约
     *
     * @param request
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "refuseProcessing")
    public String refuseProcessing(HttpServletRequest request,
                                   @RequestParam(value = "id[]") Integer[] id) {

        UserInfo userinfo = (UserInfo) request.getSession().getAttribute("userinfo");
        //如果没有登录  返回 没有登录
        if (userinfo == null) {
            return CodeEnum.noSignIn.toString();
        }
        try {
            //拒绝处理
            reserveService.refuseProcessing(userinfo, id);
        } catch (Exception e) {
            e.printStackTrace();
            //返回处理失败
            return CodeEnum.ProcessingFailed.toString();
        }

        //封装返回数据
        JSONObject retJson = new JSONObject();

        retJson.put("code", 0);
        retJson.put("msg", "拒绝处理成功");
        return retJson.toString();
    }


    /**
     * 获取医生预约成功的 预约信息
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "getAppointmentSuccessful")
    public String getAppointmentSuccessful(HttpServletRequest request,
                                           Integer pageNum, Integer limit) {
        Page page = LayUiPage.parse(pageNum, limit);
        //获取用户信息
        UserInfo userinfo = (UserInfo) request.getSession().getAttribute("userinfo");
        //获取医务信息
        Medical medical = medicalService.getMedicalByUserInfo(userinfo);
        //判断是否有医务信息
        if (medical == null) {
            //没有返回
            return CodeEnum.notDoctor.toString();
        }


        JSONObject retJson = new JSONObject();
        retJson.put("data", reserveService.patientShow(medical, true,
                ReserveFlowProgress.appointments.getKey()));
        retJson.put("code", 0);
        retJson.put("count", page.getTotal());
        retJson.put("msg", "成功");
        page.close();
        return retJson.toString(SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 将看诊的 id 加入到 session 中
     *
     * @param request
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "setReserveId")
    public String setReserveIdInSession(HttpServletRequest request,
                                        @RequestParam(value = "id") Integer id) {
        //到数据库获取 校验id 是否正确
        Reserve reserve = reserveService.selectById(id);
        if (id == null || reserve == null) {
            return CodeEnum.ProcessingFailed.toString();
        }
        //将 id 加入到 session 中
        request.getSession().setAttribute("reserveId", id);

        //返回成功
        JSONObject retJson = new JSONObject();
        retJson.put("code", 0);
        retJson.put("msg", "获取成功");
        return retJson.toString();
    }

    /**
     * 看诊结束
     *
     * @param diagnosisResult
     * @param medicineInfo
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "endVisit")
    public String endVisit(
            HttpServletRequest request,
            String diagnosisResult,
            String medicineInfo) {
        //获取session
        HttpSession session = request.getSession();
        //获取 选中 预约记录信息
        Integer reserveId = (Integer) session.getAttribute("reserveId");
        if (reserveId == null) {
            return CodeEnum.ProcessingFailed.toString();
        }
        //获取医生 用户 信息
        UserInfo userinfo = (UserInfo) session.getAttribute("userinfo");

        //添加看诊历史
        try {
            if (!medicalHistoryService.endVisit(userinfo, medicineInfo, diagnosisResult, reserveId)) {
                return CodeEnum.AcquisitionFailed.toString();
            }
        } catch (Exception e) {
            return CodeEnum.ProcessingFailed.toString();
        }
        //打包返回信息

        JSONObject retJson = new JSONObject();
        retJson.put("code", 0);
        retJson.put("msg", "看诊结束");

        return retJson.toString();
    }


}
